package edu.scau.hot.util;

import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * SerialNumber
 *
 * @author:paper
 * @since:2021/11/5-18:30
 */
public class SerialNumber{
    //流水号上限
    private static final int MAX_VALUE = 9999;
    //date格式
    private static final String FORMAT = "_yyyyMMdd_";
    private static final Format DF = new SimpleDateFormat(FORMAT);
    //时间格式
    private static final Format timeF = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    //同步数组资源
    private static final byte[] lock = new byte[0];
    /**
     * 流水号数组
     */
    private static Map<String, SerialNumber> map = new HashMap<String, SerialNumber>();
    //前缀
    private String prefix = null;
    private Date date = null;
    private int number = 1;

    /**
     * @param prefix 前缀
     * @param date
     */
    private SerialNumber(String prefix,Date date) {
        this.prefix = prefix;
        this.date = date;
    }

    public static SerialNumber newInstance(String prefix) {
        Date date = new Date();
        return newInstance(prefix,date);
    }

    public static SerialNumber newInstance(String prefix,Date date) {
        SerialNumber o = null;
        synchronized (lock) {
            String key = getKey(prefix,date);
            if (map.containsKey(key)) {
                o = map.get(key);
                int number = o.getNumber();
                if (number < MAX_VALUE) {
                    o.setNumber(number + 1);
                }
                else {
                    o.setNumber(1);
                }

            }
            else {
                o = new SerialNumber(prefix,date);
                map.put(key,o);
            }
        }
        return o;
    }

    private static String getKey(String prefix,Date date) {
        return prefix + format(date);
    }

    private static String format(Date date) {
        return DF.format(date);
    }

    public Date getDate() {
        timeF.format(date);
        return date;
    }

    @Override
    public String toString() {
        return prefix + format(date) + String.format("%04d",number);
    }

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }
}
